/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "selectinstructionlogic.h"
#include "GeneralDefine.h"
#include "programengine.h"
#include "messagelog.h"

SelectInstructionLogic::SelectInstructionLogic(int robotIdIn,ProgramSet* programSetIn,
                                               RobotIo* ioControllerIn,ProgramEngine* programEngineIn)
    {
        programSet=programSetIn;
        robotId=robotIdIn;
        ioController=ioControllerIn;
        programEngine=programEngineIn;
    }


E_PROGRAM_LOOP_RESULT SelectInstructionLogic::startSelect(int programNum,
                                                                SelectInstruction selectInstruction)
{
    programEngine->updateProgramSetRegister();

    E_PROGRAM_LOOP_RESULT endFlag = E_PROGRAM_LOOP_RESULT_NORMAL;

    int regValue,selRegValue;

    //qDebug()<<"startSelect*************(*programSet)[programNum].pc**************"<<(*programSet)[programNum].pc<<endl;
    if(D_ROBOT_REG_SIZE < selectInstruction.regNumber || 1 > selectInstruction.regNumber)
    {
        programEngine->cmdError(programNum);
        addMsg(ENUM_MSG_REMIND,"ProgramEngine","ProgramEngine",3017,robotId);
        return E_PROGRAM_LOOP_RESULT_ERROR;
    }
    else
    {
        regValue = programSet->regRList.at(selectInstruction.regNumber - 1);
    }

    if(selectInstruction.elseFlag == false)
    {
        switch (selectInstruction.valueType)
        {
        case CONSTANT:
        {
            selRegValue = selectInstruction.value;
            break;
        }
        case SEL_R:
        {
            if(D_ROBOT_REG_SIZE < selectInstruction.value || 1 > selectInstruction.value)
            {
                programEngine->cmdError(programNum);
                addMsg(ENUM_MSG_REMIND,"ProgramEngine","ProgramEngine",3017,robotId);
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
            else
            {
                selRegValue = programSet->regRList.at(selectInstruction.value - 1);
            }
            break;
        }
        }

        if(regValue == selRegValue)
        {
            if(programNum >= programSet->size())
            {
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
            else if(0==(*programSet)[programNum].size() )
            {
                qDebug()<<"select jump call error2,0==(*programSet)[programNum].size ";
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
            switch (selectInstruction.jmpCallType)
            {
            case SEL_JMP:
            {
                //                        qDebug()<<__FUNCTION__<<"**LINE***"<<__LINE__<<endl;
                QString tmpjumpLabel=(*programSet)[programNum].at(programEngine->getRunningLineFloat()).select.jumpProcess.jumpLabelStr;
                programEngine->startJump(programNum,tmpjumpLabel);
                break;
            }
            case SEL_CALL:
            {
                programEngine->startCall(programNum,(*programSet)[programNum].at(programEngine->getRunningLineFloat()).select.callProcess.programName);
                for(int k = programEngine->getRunningLineFloat(); k < (*programSet)[programNum].count();k++)
                {
                    if((*programSet)[programNum].at(k).select.elseFlag == true)
                    {
                        (*programSet)[programNum].runningLineInt = k;
//                        pCount = (*programSet)[programNum].pc+0.02;
                        break;
                    }
                }
//                for(int j = 0; j < programSet.size();j++)
//                {
//                    if((*programSet)[programNum].at(pCount).select.callProcess.programName == (*programSet)[j].programName)
//                    {
//                        startCall(programNum,j);
//                        break;
//                    }
//                }

                break;
            }
            }

        }
        else
        {
            programEngine->calculateNextLineToRun(programNum);
        }
    }
    else
    {
        switch (selectInstruction.jmpCallType)
        {
        case SEL_JMP:
        {
            //                    qDebug()<<__FUNCTION__<<"**LINE***"<<__LINE__<<endl;
            QString tmpjumpLabel=(*programSet)[programNum].at(programEngine->getRunningLineFloat()).select.jumpProcess.jumpLabelStr;
            programEngine->startJump(programNum,tmpjumpLabel);

            break;
        }
        case SEL_CALL:
        {
            programEngine->startCall(programNum,(*programSet)[programNum].at(programEngine->getRunningLineFloat()).select.callProcess.programName);
//            for(int i = 0; i < programSet.size();++i)
//            {
//                if((*programSet)[programNum].at(pCount).select.callProcess.programName == (*programSet)[i].programName)
//                {
//                    //                            startCall(programNum,i);
//                    break;
//                }
//            }
            break;
        }
        }
    }

    endFlag = programEngine->isTheLastInstruction(programNum);

    return endFlag;
}


void SelectInstructionLogic::addMsg(int messageLevel, string componentName, string messageType,
                           int messageCode, int robotId,
                           int parameter1, int parameter2, int parameter3, int parameter4,QString message)
{
    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;
   // tmpMsg.time = t1.tv_sec;


    QString infomationStr;

    switch(messageCode)
    {

    case 3017:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",寄存器指令错误，寄存器的范围超过限定的最大范围，请修改");
    }
        break;



    default:
    {

    }
    }


    tmpMsg.MessageInformation = infomationStr.toStdString();

    // qDebug()<<"53444444444444444444444"<< tmpMsg.messageCode;
    MessageLog::getInstance()->addMessage(tmpMsg);
}
